#/!/usr/bin/env python
# -*- coding: utf-8 -*-

import win32api, win32pdh, win32pdhutil, time

def GetProcInfo(pname=None):
    pid_info_dict = dict()
    name_pid_dict = dict()
    object = win32pdhutil.find_pdh_counter_localized_name("Process")
    items, instances = win32pdh.EnumObjectItems(None,None,object,win32pdh.PERF_DETAIL_WIZARD)
    instance_dict = {}
    items_dict = {}
    for item in items:
        items_dict[item] = None
    for instance in instances:
        if pname is None or pname == instance:
            if instance_dict.has_key(instance):
                instance_dict[instance] = instance_dict[instance] + 1
            else:
                instance_dict[instance] = 1
    if len(instance_dict) == 0:
        return pid_info_dict,name_pid_dict
    items = [win32pdhutil.find_pdh_counter_localized_name("ID Process")] + items[0:]
    for instance, max_instances in instance_dict.items():
        for inum in xrange(max_instances):
            hq = win32pdh.OpenQuery()
            hcs = []
            for item in items:
                path = win32pdh.MakeCounterPath((None,object, instance,None, inum, item))
                hcs.append(win32pdh.AddCounter(hq, path))
            win32pdh.CollectQueryData(hq)
            time.sleep(0.01)
            win32pdh.CollectQueryData(hq)
            proc = instance[:15]
            hc = hcs[0]
            vals = dict()
            for i in range(len(hcs)):
                hc = hcs[i]
                type, val = win32pdh.GetFormattedCounterValue(hc, win32pdh.PDH_FMT_LONG)
                vals[items[i]] = val
                if items[i] == "ID Process":
                    pid = val
            win32pdh.RemoveCounter(hc)
            vals["pname"] = instance
            pid_info_dict[pid] = vals
            if name_pid_dict.has_key(instance):
                name_pid_dict[instance].append(pid)
            else:
                name_pid_dict[instance] = [pid]
            win32pdh.CloseQuery(hq)
    return pid_info_dict,name_pid_dict

def get_pid(name):
    pid_info_dict,name_pid_dict = GetProcInfo()
    return name_pid_dict.get(name)
def get_pname(pid):
    pid_info_dict,name_pid_dict = GetProcInfo()
    return pid_info_dict[pid]["pname"]
def log_proc_info(pname=None,pid=None,log_col=[],logger=None):
    pid_info_dict, name_id_dict = GetProcInfo( pname=pname )
    if pid and pid != -1 and not pid_info_dict.has_key(pid):
        logger.info("pid not found: %d",pid)
        return False
    for id,info in pid_info_dict.items():
        if pid != -1 and id != pid:
            continue
        info_str = "[%s:%r]" % (info["pname"],info["ID Process"])
        for col in log_col:
            info_str += "%s:%r| " % (col, info[col])
        logger.info(info_str)
    return True

def get_proc_info(argv,logger):
    log_col=[
        "pname",
        #"% Processor Time",
        #"% User Time",
        #"% Privileged Time",
        #"Virtual Bytes Peak",
        #"Virtual Bytes",
        #"Page Faults/sec",
        #"Working Set Peak",
        #"Working Set",
        #"Page File Bytes Peak",
        #"Page File Bytes",
        #"Private Bytes",
        "Thread Count",
        #"Priority Base",
        #"Elapsed Time",
        #"ID Process",
        #"Creating Process ID",
        #"Pool Paged Bytes",
        #"Pool Nonpaged Bytes",
        "Handle Count",
        #"IO Read Operations/sec",
        #"IO Write Operations/sec",
        #"IO Data Operations/sec",
        #"IO Other Operations/sec",
        #"IO Read Bytes/sec",
        #"IO Write Bytes/sec",
        #"IO Data Bytes/sec",
        #"IO Other Bytes/sec",
        "Working Set - Private"
    ]
    pid = -1
    pname = "python"
    if len(argv) > 1:
        pid = int(argv[1])
        pname = get_pname(pid)

    while log_proc_info( pname=pname, pid=pid, log_col=log_col, logger=logger ):
        time.sleep(5)

if __name__ == "__main__":
    import sys
    from vavava.util import initlog
    log_file_name = "proc_info.log"
    logger = initlog(log_file_name)
    logger.info("======================")
    get_proc_info(sys.argv,logger)
